"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.InfoAction = void 0;
const chalk_1 = require("chalk");
const fs_1 = require("fs");
const os_1 = require("os");
const osName = require("os-name");
const path_1 = require("path");
const package_managers_1 = require("../lib/package-managers");
const ui_1 = require("../lib/ui");
const abstract_action_1 = require("./abstract.action");
class InfoAction extends abstract_action_1.AbstractAction {
    handle() {
        return __awaiter(this, void 0, void 0, function* () {
            displayBanner();
            yield displaySystemInformation();
            yield displayCpaasInformation();
        });
    }
}
exports.InfoAction = InfoAction;
const displayBanner = () => {
    console.info(chalk_1.default.red(ui_1.BANNER));
};
const displaySystemInformation = () => __awaiter(void 0, void 0, void 0, function* () {
    console.info(chalk_1.default.green('[System Information]'));
    console.info('OS Version     :', chalk_1.default.blue(osName(os_1.platform(), os_1.release())));
    console.info('NodeJS Version :', chalk_1.default.blue(process.version));
    yield displayPackageManagerVersion();
});
const displayPackageManagerVersion = () => __awaiter(void 0, void 0, void 0, function* () {
    const manager = yield package_managers_1.PackageManagerFactory.find();
    try {
        const version = yield manager.version();
        console.info(`${manager.name} Version    :`, chalk_1.default.blue(version));
    }
    catch (_a) {
        console.error(`${manager.name} Version    :`, chalk_1.default.red('Unknown'));
    }
});
const displayCpaasInformation = () => __awaiter(void 0, void 0, void 0, function* () {
    console.info(chalk_1.default.green('[Cpaas Information]'));
    try {
        const dependencies = yield readProjectPackageJsonDependencies();
        yield displayCpaasVersions(dependencies);
    }
    catch (_b) {
        console.error(chalk_1.default.red(ui_1.MESSAGES.NEST_INFORMATION_PACKAGE_MANAGER_FAILED));
    }
});
const readProjectPackageJsonDependencies = () => __awaiter(void 0, void 0, void 0, function* () {
    return new Promise((resolve, reject) => {
        let packageFile = path_1.join(process.cwd(), 'package.json');
        if (!fs_1.existsSync(path_1.join(process.cwd(), 'lerna.json'))) {
            packageFile = path_1.join(process.cwd(), '../../package.json');
        }
        fs_1.readFile(packageFile, (error, buffer) => {
            if (error !== undefined && error !== null) {
                reject(error);
            }
            else {
                resolve(JSON.parse(buffer.toString()).dependencies);
            }
        });
    });
});
const readDependenciesPackageVersion = (dependencyName) => __awaiter(void 0, void 0, void 0, function* () {
    let packageFile = path_1.join(process.cwd(), 'node_modules', dependencyName, 'package.json');
    if (!fs_1.existsSync(packageFile)) {
        packageFile = path_1.join(process.cwd(), '../../node_modules', dependencyName, 'package.json');
        if (!fs_1.existsSync(packageFile)) {
            packageFile = path_1.join(process.cwd(), '../../../node_modules', dependencyName, 'package.json');
            if (!fs_1.existsSync(packageFile)) {
                return '';
            }
        }
    }
    return new Promise((resolve, reject) => {
        fs_1.readFile(packageFile, (error, buffer) => {
            if (error !== undefined && error !== null) {
                reject(error);
            }
            else {
                resolve(JSON.parse(buffer.toString()).version);
            }
        });
    });
});
const displayCpaasVersions = (dependencies) => __awaiter(void 0, void 0, void 0, function* () {
    const addRealVersionDepends = [];
    const buildCpaasVersionsPackageMessage = buildCpaasVersionsMessage(dependencies);
    if (!buildCpaasVersionsPackageMessage.find((item) => item.name === 'choerodon-ui')) {
        buildCpaasVersionsPackageMessage.push({
            name: 'choerodon-ui',
            value: '*',
        });
    }
    if (!buildCpaasVersionsPackageMessage.find((item) => item.name === 'cpaas-boot')) {
        buildCpaasVersionsPackageMessage.push({
            name: 'cpaas-boot',
            value: '*',
        });
    }
    if (!buildCpaasVersionsPackageMessage.find((item) => item.name === 'cpaas-cli')) {
        buildCpaasVersionsPackageMessage.push({
            name: 'cpaas-cli',
            value: '*',
        });
    }
    for (const dependency of buildCpaasVersionsPackageMessage) {
        const dependenciesPackageVersion = yield readDependenciesPackageVersion(dependency.name);
        if (!dependenciesPackageVersion) {
            continue;
        }
        addRealVersionDepends.push(Object.assign(Object.assign({}, dependency), { value: dependenciesPackageVersion }));
    }
    format(addRealVersionDepends).forEach((dependency) => {
        console.info(dependency.name, chalk_1.default.blue(dependency.value));
    });
});
const buildCpaasVersionsMessage = (dependencies) => {
    const cpaasDependencies = collectCpaasDependencies(dependencies);
    return cpaasDependencies;
};
const collectCpaasDependencies = (dependencies) => {
    const cpaasDependencies = [];
    Object.keys(dependencies).forEach((key) => {
        if (key.indexOf('cpaas-') > -1 || key === 'choerodon-ui') {
            cpaasDependencies.push({
                name: `${key}`,
                value: dependencies[key],
            });
        }
    });
    return cpaasDependencies;
};
const format = (dependencies) => {
    if (dependencies.length === 0) {
        return [];
    }
    const sorted = dependencies
        .sort((dependencyA, dependencyB) => dependencyB.name.localeCompare(dependencyA.name))
        .sort((dependencyA, dependencyB) => dependencyB.name.length - dependencyA.name.length);
    const length = sorted[0].name.length;
    sorted.forEach((dependency) => {
        if (dependency.name.length < length) {
            dependency.name = rightPad(dependency.name, length);
        }
        dependency.name = dependency.name.concat('  version :');
        dependency.value = dependency.value.replace(/(\^|\~)/, '');
    });
    return sorted;
};
const rightPad = (name, length) => {
    while (name.length < length) {
        name = name.concat(' ');
    }
    return name;
};
